<template>
  <Teleport to="body">
    <div class="fixed top-4 right-4 z-[9999] flex flex-col gap-3 pointer-events-none">
      <TransitionGroup name="toast">
        <div
          v-for="toast in toasts"
          :key="toast.id"
          :class="[
            'pointer-events-auto',
            'min-w-[320px] max-w-md',
            'bg-white dark:bg-gray-800',
            'rounded-lg shadow-2xl',
            'border-l-4',
            'p-4 pr-12',
            'relative overflow-hidden',
            'transform transition-all duration-300',
            getToastColorClass(toast.type)
          ]"
        >
          <!-- 进度条 -->
          <div
            v-if="toast.duration"
            class="absolute bottom-0 left-0 h-1 bg-current opacity-20 transition-all ease-linear"
            :style="{ width: getProgressWidth(toast), transitionDuration: toast.duration + 'ms' }"
          ></div>

          <div class="flex items-start gap-3">
            <!-- 图标 -->
            <div class="flex-shrink-0 mt-0.5">
              <Icon
                :name="getToastIcon(toast.type)"
                :class="['w-5 h-5', getToastIconColor(toast.type)]"
              />
            </div>

            <!-- 内容 -->
            <div class="flex-1 min-w-0">
              <h4 v-if="toast.title" class="font-semibold text-gray-900 dark:text-gray-100 mb-1">
                {{ toast.title }}
              </h4>
              <p class="text-sm text-gray-600 dark:text-gray-400 break-words">
                {{ toast.message }}
              </p>
            </div>

            <!-- 关闭按钮 -->
            <button
              @click="removeToast(toast.id)"
              class="absolute top-3 right-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors"
            >
              <Icon name="heroicons:x-mark" class="w-5 h-5" />
            </button>
          </div>
        </div>
      </TransitionGroup>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
interface Toast {
  id: string
  type: 'success' | 'error' | 'warning' | 'info'
  title?: string
  message: string
  duration?: number
  createdAt: number
}

const toasts = ref<Toast[]>([])

const getToastColorClass = (type: Toast['type']) => {
  const colors = {
    success: 'border-green-500',
    error: 'border-red-500',
    warning: 'border-yellow-500',
    info: 'border-blue-500',
  }
  return colors[type]
}

const getToastIcon = (type: Toast['type']) => {
  const icons = {
    success: 'heroicons:check-circle',
    error: 'heroicons:x-circle',
    warning: 'heroicons:exclamation-triangle',
    info: 'heroicons:information-circle',
  }
  return icons[type]
}

const getToastIconColor = (type: Toast['type']) => {
  const colors = {
    success: 'text-green-500',
    error: 'text-red-500',
    warning: 'text-yellow-500',
    info: 'text-blue-500',
  }
  return colors[type]
}

const getProgressWidth = (toast: Toast) => {
  if (!toast.duration) return '0%'
  const elapsed = Date.now() - toast.createdAt
  const remaining = Math.max(0, toast.duration - elapsed)
  return `${(remaining / toast.duration) * 100}%`
}

const addToast = (toast: Omit<Toast, 'id' | 'createdAt'>) => {
  const id = Math.random().toString(36).substr(2, 9)
  const newToast: Toast = {
    ...toast,
    id,
    createdAt: Date.now(),
  }
  
  toasts.value.push(newToast)

  if (toast.duration) {
    setTimeout(() => {
      removeToast(id)
    }, toast.duration)
  }
}

const removeToast = (id: string) => {
  const index = toasts.value.findIndex(t => t.id === id)
  if (index > -1) {
    toasts.value.splice(index, 1)
  }
}

// 暴露方法给外部使用
defineExpose({
  addToast,
  removeToast,
})
</script>

<style scoped>
.toast-enter-active,
.toast-leave-active {
  transition: all 0.3s ease;
}

.toast-enter-from {
  opacity: 0;
  transform: translateX(100%);
}

.toast-leave-to {
  opacity: 0;
  transform: translateX(100%) scale(0.8);
}

.toast-move {
  transition: transform 0.3s ease;
}
</style>

